home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Misc / emu / fbzx.lha / fbzx / spk_ay.c < prev    next >
C/C++ Source or Header  |  2004-01-04  |  8KB  |  343 lines

  1. #include "emulator.h"
  2. #include "sound.h"
  3. #include <stdlib.h>
  4.  
  5. /* emulates the AY-3-8912 during TSTADOS tstates */
  6.  
  7. inline void play_ay (unsigned int tstados) {
  8.  
  9.     if (!ordenador.ay_emul)
  10.         return;
  11.  
  12.     ordenador.tst_ay += tstados;
  13.     ordenador.tst_ay2 += tstados;
  14.  
  15.     if (ordenador.tst_ay2 > 255) {
  16.         ordenador.tst_ay2 -= 256;
  17.         if ((ordenador.ay_registers[11])
  18.             || (ordenador.ay_registers[12])) {
  19.             if (ordenador.aych_envel)
  20.                 ordenador.aych_envel--;
  21.             else {
  22.                 ordenador.aych_envel = (((unsigned int) ordenador.ay_registers[11]) + 256 * ((unsigned int) (ordenador.ay_registers[12])));
  23.                 if (ordenador.ay_envel_way & 0x02)    // start cycle?
  24.                     switch ((ordenador.
  25.                          ay_registers[13]) & 0x0F)
  26.                     {
  27.                     case 0:
  28.                     case 1:
  29.                     case 2:
  30.                     case 3:
  31.                     case 8:
  32.                     case 9:
  33.                     case 10:
  34.                     case 11:
  35.                         ordenador.ay_envel_way = 4;    // cycle started and decrementing
  36.                         ordenador.ay_envel_value = 16;
  37.                         break;
  38.                     default:
  39.                         ordenador.ay_envel_way = 5;    // cycle started and incrementing
  40.                         ordenador.ay_envel_value = -1;
  41.                     }
  42.                 if (ordenador.ay_envel_way & 0x04)
  43.                 {    // cycle started?
  44.                     switch ((ordenador.
  45.                          ay_registers[13]) & 0x0F)
  46.                     {
  47.                     case 0:
  48.                     case 1:
  49.                     case 2:
  50.                     case 3:
  51.                     case 9:
  52.                         ordenador.ay_envel_value--;
  53.                         if (ordenador.
  54.                             ay_envel_value == 0)
  55.                             ordenador.ay_envel_way = 0;    // end
  56.                         break;
  57.  
  58.                     case 4:
  59.                     case 5:
  60.                     case 6:
  61.                     case 7:
  62.                     case 15:
  63.                         ordenador.ay_envel_value++;
  64.                         if (ordenador.
  65.                             ay_envel_value == 16)
  66.                         {
  67.                             ordenador.
  68.                                 ay_envel_value
  69.                                 = 0;
  70.                             ordenador.ay_envel_way = 0;    // end
  71.                         }
  72.                         break;
  73.  
  74.                     case 8:
  75.                         ordenador.ay_envel_value--;
  76.                         if (ordenador.
  77.                             ay_envel_value == -1)
  78.                             ordenador.ay_envel_value = 15;    // repeat
  79.                         break;
  80.  
  81.                     case 10:
  82.                     case 14:
  83.                         if (ordenador.
  84.                             ay_envel_way & 0x01)
  85.                             ordenador.
  86.                                 ay_envel_value++;
  87.                         else
  88.                             ordenador.
  89.                                 ay_envel_value--;
  90.                         if (ordenador.
  91.                             ay_envel_value == 16)
  92.                         {
  93.                             ordenador.
  94.                                 ay_envel_value
  95.                                 = 14;
  96.                             ordenador.
  97.                                 ay_envel_way =
  98.                                 4;
  99.                         }
  100.                         if (ordenador.
  101.                             ay_envel_value == -1)
  102.                         {
  103.                             ordenador.
  104.                                 ay_envel_value
  105.                                 = 1;
  106.                             ordenador.
  107.                                 ay_envel_way =
  108.                                 5;
  109.                         }
  110.                         break;
  111.  
  112.                     case 11:
  113.                         ordenador.ay_envel_value--;
  114.                         if (ordenador.
  115.                             ay_envel_value == -1)
  116.                         {
  117.                             ordenador.
  118.                                 ay_envel_value
  119.                                 = 15;
  120.                             ordenador.ay_envel_way = 0;    // end
  121.                         }
  122.                         break;
  123.  
  124.                     case 12:
  125.                         ordenador.ay_envel_value++;
  126.                         if (ordenador.
  127.                             ay_envel_value == 16)
  128.                             ordenador.
  129.                                 ay_envel_value
  130.                                 = 0;
  131.                         break;
  132.  
  133.                     case 13:
  134.                         ordenador.ay_envel_value++;
  135.                         if (ordenador.
  136.                             ay_envel_value == 15)
  137.                             ordenador.ay_envel_way = 0;    // end
  138.                         break;
  139.                     }
  140.                 }
  141.             }
  142.         }
  143.         else
  144.             ordenador.ay_envel_value = 15;
  145.     }
  146.  
  147.     while (ordenador.tst_ay >= 16)
  148.     {
  149.         ordenador.tst_ay -= 16;
  150.  
  151.         if ((ordenador.ay_registers[0])
  152.             || (ordenador.ay_registers[1]))
  153.         {
  154.             if (ordenador.aych_a)
  155.                 ordenador.aych_a--;
  156.             else
  157.             {
  158.                 ordenador.ayval_a = 1 - ordenador.ayval_a;
  159.                 ordenador.aych_a =
  160.                     (((unsigned int) ordenador.
  161.                       ay_registers[0]) +
  162.                      256 *
  163.                      ((unsigned
  164.                        int) ((ordenador.
  165.                           ay_registers[1]) & 0x0F))) /
  166.                     2;
  167.             }
  168.         }
  169.         else
  170.             ordenador.ayval_a = 0;
  171.  
  172.         if ((ordenador.ay_registers[2])
  173.             || (ordenador.ay_registers[3]))
  174.         {
  175.             if (ordenador.aych_b)
  176.                 ordenador.aych_b--;
  177.             else
  178.             {
  179.                 ordenador.ayval_b = 1 - ordenador.ayval_b;
  180.                 ordenador.aych_b =
  181.                     (((unsigned int) ordenador.
  182.                       ay_registers[2]) +
  183.                      256 *
  184.                      ((unsigned
  185.                        int) ((ordenador.
  186.                           ay_registers[3]) & 0x0F))) /
  187.                     2;
  188.             }
  189.         }
  190.         else
  191.             ordenador.ayval_b = 0;
  192.  
  193.         if ((ordenador.ay_registers[4])
  194.             || (ordenador.ay_registers[5]))
  195.         {
  196.             if (ordenador.aych_c)
  197.                 ordenador.aych_c--;
  198.             else
  199.             {
  200.                 ordenador.ayval_c = 1 - ordenador.ayval_c;
  201.                 ordenador.aych_c =
  202.                     (((unsigned int) ordenador.
  203.                       ay_registers[4]) +
  204.                      256 *
  205.                      ((unsigned
  206.                        int) ((ordenador.
  207.                           ay_registers[5]) & 0x0F))) /
  208.                     2;
  209.             }
  210.         }
  211.         else
  212.             ordenador.ayval_c = 0;
  213.  
  214.         if (ordenador.ay_registers[6])
  215.         {
  216.             if (ordenador.aych_n)
  217.                 ordenador.aych_n--;
  218.             else
  219.             {
  220.                 ordenador.ayval_n = 1 - ordenador.ayval_n;
  221.                 ordenador.aych_n =
  222.                     ((((unsigned int) ordenador.
  223.                        ay_registers[6]) & 0x1F) +
  224.                      (rand () % 3)) / 2;
  225.                 if (ordenador.aych_n > 16)
  226.                     ordenador.aych_n = 16;
  227.             }
  228.         }
  229.         else
  230.             ordenador.ayval_n = 0;
  231.  
  232.         if (ordenador.ay_registers[8] & 0x10)
  233.             ordenador.vol_a =
  234.                 (unsigned
  235.                  char) ((((unsigned int) ordenador.
  236.                       ay_envel_value)) *
  237.                     (unsigned int) ordenador.volume) / 15;
  238.         else
  239.             ordenador.vol_a =
  240.                 (unsigned
  241.                  char) ((((unsigned int) (ordenador.
  242.                               ay_registers[8] &
  243.                               0x0F)) *
  244.                      (unsigned int) ordenador.volume) /
  245.                     15);
  246.  
  247.         if (ordenador.ay_registers[10] & 0x10)
  248.             ordenador.vol_c =
  249.                 (unsigned
  250.                  char) ((((unsigned int) ordenador.
  251.                       ay_envel_value)) *
  252.                     (unsigned int) ordenador.volume) / 15;
  253.         else
  254.             ordenador.vol_c =
  255.                 (unsigned
  256.                  char) ((((unsigned int) (ordenador.
  257.                               ay_registers[10] &
  258.                               0x0F)) *
  259.                      (unsigned int) ordenador.volume) /
  260.                     15);
  261.  
  262.         if (ordenador.ay_registers[9] & 0x10)
  263.             ordenador.vol_b =
  264.                 (unsigned
  265.                  char) ((((unsigned int) ordenador.
  266.                       ay_envel_value)) *
  267.                     (unsigned int) ordenador.volume) / 15;
  268.         else
  269.             ordenador.vol_b =
  270.                 (unsigned
  271.                  char) ((((unsigned int) (ordenador.
  272.                               ay_registers[9] &
  273.                               0x0F)) *
  274.                      (unsigned int) ordenador.volume) /
  275.                     15);
  276.  
  277.     }
  278. }
  279.  
  280.  
  281. /* Creates the sound buffer during the TSTADOS tstate that the Z80 used to
  282.    execute last instruction */
  283.  
  284. inline void play_sound (unsigned int tstados) {
  285.  
  286.     static int bucle;
  287.     static int value;
  288.     static unsigned char sample_v;
  289.  
  290.     ordenador.tstados_counter_sound += tstados;
  291.  
  292.     while (ordenador.tstados_counter_sound >= ordenador.tst_sample)    {
  293.  
  294.         ordenador.tstados_counter_sound -= ordenador.tst_sample;
  295.  
  296.         for (bucle = 0; bucle < ordenador.increment; bucle++) {
  297.             sample_v = ordenador.sample1b[bucle];
  298.             if ((ordenador.sound_bit) && (sample_v)) {
  299.                 ordenador.sound_current_value+=(ordenador.tst_sample/8);
  300.                 if(ordenador.sound_current_value>ordenador.volume)
  301.                     ordenador.sound_current_value = ordenador.volume;
  302.             } else {
  303.                 if(ordenador.sound_current_value>=(ordenador.tst_sample/8))
  304.                     ordenador.sound_current_value-=((ordenador.tst_sample)/8);
  305.                 else
  306.                     ordenador.sound_current_value = 0;
  307.             }
  308.             value = ordenador.sound_current_value;
  309.             if (ordenador.ay_emul) {    // if emulation is ON, emulate it
  310.                 if ((ordenador.ayval_a) && (sample_v)
  311.                     && (!(ordenador.ay_registers[7] & 0x01)))
  312.                     value += (int) ordenador.vol_a;
  313.                 if ((ordenador.ayval_b) && (sample_v)
  314.                     && (!(ordenador.ay_registers[7] & 0x02)))
  315.                     value += (int) ordenador.vol_b;
  316.                 if ((ordenador.ayval_c) && (sample_v)
  317.                     && (!(ordenador.ay_registers[7] & 0x04)))
  318.                     value += (int) ordenador.vol_c;
  319.                 if ((ordenador.ayval_n) && (sample_v)
  320.                     && (!(ordenador.ay_registers[7] & 0x08)))
  321.                     value += (int) ordenador.vol_a;
  322.                 if ((ordenador.ayval_n) && (sample_v)
  323.                     && (!(ordenador.ay_registers[7] & 0x10)))
  324.                     value += (int) ordenador.vol_b;
  325.                 if ((ordenador.ayval_n) && (sample_v)
  326.                     && (!(ordenador.ay_registers[7] & 0x20)))
  327.                     value += (int) ordenador.vol_c;
  328.             }
  329.             if (value > 255)
  330.                 value = 255;
  331.             sample_v = (char)(value - (unsigned int)ordenador.sign);
  332.             *ordenador.current_buffer =    sample_v;            
  333.             ordenador.current_buffer++;            
  334.         }
  335.         ordenador.sound_cuantity++;
  336.  
  337.         if (ordenador.sound_cuantity == ordenador.buffer_len) {        // buffer filled
  338.             sound_play();
  339.             ordenador.sound_cuantity = 0;
  340.         }
  341.     }
  342. }
  343.